/**************************************************************************//**
* @file     CANOpenSlave.c
* @brief    Handle CAN bus as a slave node.
* @author   Shawn Huang
* @date
* @version
*******************************************************************************
* Copyright (c) DeltaTec 2017
* All right reserved.
******************************************************************************/

/******************************************************************************
* COMPILATION OPTION
******************************************************************************/

/******************************************************************************
* INCLUDE FILE
******************************************************************************/
// Include system file
#include "r_cg_can.h"

// Include project file
#include "CAN.h"
#include "fet.h"
#include "nvm.h"
#include "control.h"
#include "faults.h"
#include "Main.h"
#include "Switches.h"
#include "Joystick.h"
#include "Serial.h"
#include "Battery.h"
#include "BMS_CAN.h"
#include "RemoteCtrlCan.h"

/******************************************************************************
* DEFINE DESCRIPTION
******************************************************************************/
#define CAN_DI_DEBUG	(0)
/******************************************************************************
* ENUM DESCRIPTION
******************************************************************************/

/******************************************************************************
* STRUCTURE DESCRIPTION
******************************************************************************/
struct ST_MC_DATA stMcData = {0};

/******************************************************************************
* VARIABLE DESCRIPTION
******************************************************************************/
UINT16  u16CanLostCnt = 0;
UINT32 u16Message0LostCnt = 0;
UINT16 u16Message0LostCnt_First = 0;
UINT8 u8_first_run = 1;
/******************************************************************************
* CONSTANT DESCRIPTION
******************************************************************************/

/******************************************************************************
* FUNCTION PROTOTYPE
******************************************************************************/

/******************************************************************************
* FUNCTION DESCRIPTION
******************************************************************************/

/*************************************************************************//**
* @ingroup communicate
* @brief   initialize CAN boadrate and receive ID
* @param   none
* @return  none
*****************************************************************************/
typedef struct
{
	uint8_t buffer_num;
	uint16_t id_hi;
	uint16_t id_lo;
	uint16_t mask_hi;
	uint16_t mask_lo;
}structCanFitter;
const structCanFitter stCanFitterArr[5] = 
{
	{0,0x8000,0xf100,0XFFF0,0XFFFF},//充电器,实际接收0x00F100-0x0FF100
	{1,0x0000,0x0181,0XFFFF,0XFFFF},//实际接收181//0x180-0x18F
	{2,0x0000,0x0280,0XFFFF,0XFFF0},//实际接收0x280-0x28F
	{3,0x9800,0xFFF4,0XFFF8,0XFFFF},//实际接收0x1800FFF4-0x1807FFF4
	{4,0x9800,0xD2F4,0XFF00,0XFFFF},//实际接收0x1800D2F4-0x18FFD2F4
};
void vCanInitial(void)
{
	UINT8 i=0;
    R_CAN0_Create();
    // set baudrate
    R_CAN0_Set_Baudrate(BAURDRATE);
    // set receive box ID (total 16 buffer)
    // NOTE: receive box MUST be set in turn, MUST NOT out of sequence!
    /*
    for(i=0;i<5;i++)
    {
		R_CAN0_Set_Rx_Buffer(
			stCanFitterArr[i].buffer_num,
			stCanFitterArr[i].id_hi,
			stCanFitterArr[i].id_lo,
			stCanFitterArr[i].mask_hi,
			stCanFitterArr[i].mask_lo
		);
	}*/
	R_CAN0_Set_Rx_Buffer(0,0x8000,0xf100,0XFFF0,0XFFFF);
	R_CAN0_Set_Rx_Buffer(1,0x0000,0x0181,0XFFFF,0XFFFF);
	R_CAN0_Set_Rx_Buffer(2,0x0000,0x0280,0XFFFF,0XFFF0);
	R_CAN0_Set_Rx_Buffer(3,0x9800,0xFFF4,0XFFF8,0XFFFF);
	R_CAN0_Set_Rx_Buffer(4,0x9800,0xD2F4,0XFF00,0XFFFF);
}

/*************************************************************************//**
* @ingroup communicate
* @brief   receive data from CAN bus
* @param   none
* @return  none
*****************************************************************************/
//
structCanTxFifo stCanTxFifo = {0};
typedef struct
{
	UINT8 u8_length;
	UINT8 u8_buffer[8];
	UINT16 u16_id_hi;
	UINT16 u16_id_lo;
}structFastRxBuff;
structFastRxBuff stFastRxBuff = {0};
//Interrupt Call//
void vCanFastRxProcess(void)//200us,中断,CAN RX 快速轮询,只拷贝数据，置位标志位
{
	//UINT8 u8_length=0,u8_buffer[8];
	//UINT16 u16_id_hi=0,u16_id_lo=0;
	
	if (R_CAN0_Is_Received(0) == TRUE)
    {
        stFastRxBuff.u8_length = R_CAN0_Read(0, &stFastRxBuff.u16_id_hi, &stFastRxBuff.u16_id_lo, stFastRxBuff.u8_buffer);
	}
	if (R_CAN0_Is_Received(1) == TRUE)
    {
        stFastRxBuff.u8_length = R_CAN0_Read(1, &stFastRxBuff.u16_id_hi, &stFastRxBuff.u16_id_lo, stFastRxBuff.u8_buffer);
		vRemoteCtrlCanFastRxCallBack(stFastRxBuff.u16_id_hi,stFastRxBuff.u16_id_lo,stFastRxBuff.u8_length,stFastRxBuff.u8_buffer);
	}
	if (R_CAN0_Is_Received(2) == TRUE)
    {
        stFastRxBuff.u8_length = R_CAN0_Read(2, &stFastRxBuff.u16_id_hi, &stFastRxBuff.u16_id_lo, stFastRxBuff.u8_buffer);
	}
	if (R_CAN0_Is_Received(3) == TRUE)
    {
        stFastRxBuff.u8_length = R_CAN0_Read(3, &stFastRxBuff.u16_id_hi, &stFastRxBuff.u16_id_lo, stFastRxBuff.u8_buffer);
		vBMSCanFastRxCallBack(stFastRxBuff.u16_id_hi,stFastRxBuff.u16_id_lo,stFastRxBuff.u8_length,stFastRxBuff.u8_buffer);
	}
	if (R_CAN0_Is_Received(4) == TRUE)
    {
        stFastRxBuff.u8_length = R_CAN0_Read(4, &stFastRxBuff.u16_id_hi, &stFastRxBuff.u16_id_lo, stFastRxBuff.u8_buffer);
	}
}
/////////////////////Main Call////////////////////////
void vCanRxProcess(void)//10ms 主循环
{
	vProcBmsCanRx();
	vRemoteCtrlCanRx();
}
void vCanTxProcess(void)//10ms 主循环
{
	vProcBmsCanTx();
	vRemoteCtrlCanTx();
}

/*
CAN,队列发送,1ms间隔
*/
UINT8 u8GetCanMasterDriveRxFifoTotalLen(structCanTxFifo *pFifo)
{
	return pFifo->u8TotalLen;
}
void vClearCanTxFifo(structCanTxFifo *pFifo)
{
	pFifo->u8Head = 0;
	pFifo->u8Rear = 0;
	pFifo->u8TotalLen = 0;
}
void vPushCanTxFifo(structCanTxFifo *pFifo,UINT16 id_hi, UINT16 id_lo, UINT8 length, UINT8 * tx_buf)

{
	structCanTxMsg CanRxMsg = {0};
	UINT8 i;
	if(pFifo->u8TotalLen<CanSendMsgMaxLen)
	{
		CanRxMsg.u16_id_hi = id_hi;
		CanRxMsg.u16_id_Lo = id_lo;
		CanRxMsg.u8Length = length;
		for(i=0;i<CanRxMsg.u8Length;i++)
		{
			CanRxMsg.u8_buffer[i] = tx_buf[i];
		}	
		//DI();
		pFifo->CanTxMsg[pFifo->u8Head] = CanRxMsg;
		pFifo->u8TotalLen++;
		pFifo->u8Head++;
		if(pFifo->u8Head>=CanSendMsgMaxLen)
		{
			pFifo->u8Head = 0;
		}
		//EI();
	}
}
void vPopCanTxFifo(structCanTxFifo *pFifo,structCanTxMsg *pCanRxMsg)
{
	if(pFifo->u8TotalLen>0)
	{
		//DI();
		*pCanRxMsg = pFifo->CanTxMsg[pFifo->u8Rear];
		pFifo->u8TotalLen--;
		pFifo->u8Rear++;
		if(pFifo->u8Rear>=CanSendMsgMaxLen)
		{
			pFifo->u8Rear = 0;
		}
		//EI();
	}
}

void vCanTxFifoProcess(void)//1ms 主循环
{
	structCanTxMsg CanTxMsg = {0};
	UINT8 i=0;
	/*
	1.缓冲区需要发送数据
	2.有空闲的CAN物理发送缓冲
	3.1ms最多调1次 vSendCanTxBuff
	*/
	if((u8GetCanMasterDriveRxFifoTotalLen(&stCanTxFifo)>0)&&(1 == R_CAN0_Is_Transmitted(0)))
	{
		vPopCanTxFifo(&stCanTxFifo,&CanTxMsg);
		R_CAN0_Send(CanTxMsg.u16_id_hi, CanTxMsg.u16_id_Lo, CanTxMsg.u8Length, &CanTxMsg.u8_buffer[0]);
	}
	/*
	while(
			(u8GetCanMasterDriveRxFifoTotalLen(&stCanTxFifo)>0)&&
			(
				(1 == u8IsCanTransmitted(0))||
				(1 == u8IsCanTransmitted(1))||
				(1 == u8IsCanTransmitted(2))||
				(1 == u8IsCanTransmitted(3))
			)&&
			(i<4)
	)
	{
		vPopCanTxFifo(&stCanTxFifo,&CanTxMsg);
		vSendCanTxBuff(CanTxMsg.u16_id_hi, CanTxMsg.u16_id_Lo, CanTxMsg.u8Length, &CanTxMsg.u8_buffer[0]);
		i++;
	}

	*/
}


#if 0
void vCanRxProcess(void)
{
   UINT8  u8_buffer[8];
    UINT16 u16_id_hi, u16_id_lo, u16_hmi_addr, u16_hmi_data;
    UINT8  u8_length;
   UINT8  i;
   UINT8 * pb;
    UINT8 EN_GPS_FLAG = 0;

   //0x182 TPDO message from GPS
    if (R_CAN0_Is_Received(RX_TPDO1_GPS) == TRUE)
    {
        u8_length = R_CAN0_Read(RX_TPDO1_GPS, &u16_id_hi, &u16_id_lo, u8_buffer);
        // parse message
        if (u8_length == 2)
        {
            MAIN_Data.bFullLockMachine = (u8_buffer[0] == 0x01) ? 1 : 0;
            MAIN_Data.bSemiLockMachine = (u8_buffer[0] == 0x02) ? 1 : 0;
            MAIN_Data.bLookingMachine = (u8_buffer[1] == 0x01) ? 1 : 0;
            //bPCModeFlag = (u8_buffer[1] == 0x80) ? 1 : 0;
        }
    }

   if(GPS_ENABLE_FLAG == 0 || GPS_ENABLE_FLAG == 58)    //disable hongxin GPS
   {
      MAIN_Data.bFullLockMachine = 0;
      MAIN_Data.bSemiLockMachine = 0;
      MAIN_Data.bLookingMachine = 0;
   }

   //0x024A TPDO message from GPSLIB    �Զ�����GPS
   if(R_CAN0_Is_Received(RX_TPDO_GPSLIB) == TRUE) //hongxin GPS
   {
      u16Message0LostCnt = 0;

      if(u16Message0LostCnt_First < 20) u16Message0LostCnt_First++;
      else EN_GPS_FLAG = 1;

      if((lift_setup.bSpare1 != 1 && lift_setup.bSpare1 != 58) && (EN_GPS_FLAG == 1)) //if(!lift_options.fBattery_drain)
      {
          pb = &lift_setup.bSpare1;
         *pb = 1;
         record_write_verify(lift_setup.bLiftType, sizeof(struct nvm_lift_setup), (UINT8 *)&lift_setup);
      }
       u8_length = R_CAN0_Read(RX_TPDO_GPSLIB, &u16_id_hi, &u16_id_lo, u8_buffer);
       // parse message
      if ((u16_id_lo == GPS_TPDO1_CODE) ||(u16_id_lo == GPS_TPDO2_CODE)||(u16_id_lo == GPS_TPDO3_CODE))
      {
         stECULockLibCANdata.au8ECULockCANRXData[0] = 0x00;
         stECULockLibCANdata.au8ECULockCANRXData[1] = (UINT8)(u16_id_lo & 0xFF);
         stECULockLibCANdata.au8ECULockCANRXData[2] = (UINT8)((u16_id_lo >> 8) & 0xFF);
         stECULockLibCANdata.au8ECULockCANRXData[3] = (UINT8)(u16_id_hi & 0xFF);
         stECULockLibCANdata.au8ECULockCANRXData[4] = (UINT8)((u16_id_hi >> 8) & 0xFF);
         for(i=0;i<8;i++)
         {
            stECULockLibCANdata.au8ECULockCANRXData[i+5] = u8_buffer[i];
         }

      }
      else if (u16_id_lo == GPS_TPDO4_CODE)
      {
         if (u8_buffer[0] == 2)
         {
            stECULockLibCANdata.u8GPS4gState = (u8_buffer[3] & 0x01);
         }

      }
   }
   else if(R_CAN0_Is_Received(3) == TRUE)  //0x702 dingli GPS
   {
      u16Message0LostCnt = 0;

      if(u16Message0LostCnt_First < 20) u16Message0LostCnt_First++;
      else EN_GPS_FLAG = 2;

      if((lift_setup.bSpare1 != 2 && lift_setup.bSpare1 != 58) && (EN_GPS_FLAG ==2))  //if(!lift_options.fBattery_drain)
      {
         pb = &lift_setup.bSpare1;
         *pb = 2;
         record_write_verify(lift_setup.bLiftType, sizeof(struct nvm_lift_setup), (UINT8 *)&lift_setup);
      }
   }
   else
   {
      if(GPS_ENABLE_FLAG == 2)
      {
         if(u16Message0LostCnt < 500)// 5s   MESSAGE_0_LOST_TIME)
           {
               u16Message0LostCnt++;
           }
           else
           {
               //// set fault
               xfer.fGpsLostCommunication = 1;
               NVM_SaveFault(FAULT_GPS_COM_ERROR);
           }
      }
   }

   if(1 == R_CAN0_Is_Received(2))     //0x282
   {
     //read first order lock
     if(R_CAN0_Read(2, &u16_id_hi, &u16_id_lo, u8_buffer) == 8)
     {
      //lock lift
      if(u8_buffer[0] & 0x01)
      {
         unLiftlocksets.bit.bFirstLockLift = 1;
         unLiftlocksets.bit.bSecondLockLift = 0;
      }
      else if(u8_buffer[0] & 0x02)
      {
         unLiftlocksets.bit.bFirstLockLift = 0;
         unLiftlocksets.bit.bSecondLockLift = 1;
      }
      //unlock lift
      else
      {
         unLiftlocksets.bit.bFirstLockLift = 0;
         unLiftlocksets.bit.bSecondLockLift = 0;
         MAIN_Data.bFirstLockLift = 0;
         MAIN_Data.bSecondLockLift = 0;
         MAIN_Data.bLockLiftState = MAIN_Data.bFirstLockLift || MAIN_Data.bSecondLockLift;
      }

      if((unLiftlocksets.bit.bFirstLockLift_old != unLiftlocksets.bit.bFirstLockLift) ||
            (unLiftlocksets.bit.bSecondLockLift_old != unLiftlocksets.bit.bSecondLockLift))
         u8_first_run = TRUE;

      if(u8_first_run == TRUE)
      {
         NVM_SaveGPSLockState();
         u8_first_run = FALSE;
      }
      unLiftlocksets.bit.bFirstLockLift_old = unLiftlocksets.bit.bFirstLockLift;
      unLiftlocksets.bit.bSecondLockLift_old = unLiftlocksets.bit.bSecondLockLift;
     }
   }

   if(GPS_ENABLE_FLAG == 0 || GPS_ENABLE_FLAG == 58)
   {
      unLiftlocksets.bit.bFirstLockLift = 0;
      unLiftlocksets.bit.bSecondLockLift = 0;
      MAIN_Data.bFirstLockLift = 0;
      MAIN_Data.bSecondLockLift = 0;
      MAIN_Data.bLockLiftState = 0;
   }
}

/*************************************************************************//**
* @ingroup communicate
* @brief   tansmit data to CAN bus
* @param   none
* @return  none
*****************************************************************************/
extern unsigned char u8J2_4Value;
void vCanTxProcess(void)
{
   UINT8 u8_buffer[8];
    static UINT16 u16_Can_Tx_Cnt = 0;
    static UINT16 u16_Can_Tx_Cnt_1 = 0;
   static UINT16 u16_Can_Tx_Cnt_2 = 0;

    static UINT16 u16_Can_Tx_Cnt_20ms = 0;
    static UINT16 u16_Can_Tx_Cnt_5s = 0;
    static UINT16 u16_Can_Tx_Cnt_500ms = 0;
    static UINT16 u16_Can_Tx_Cnt_10min = 0;

  static UINT16 u16_old_fet_word = 0;
  static UINT16 u16_old_switch_word = 0;
  static UINT16 u16_old_joystick_word = 0;
  static UINT16 u16_old_status_word = 0;
  static UINT16 u16_old_fault_word1 = 0;
  static UINT16 u16_old_fault_word2 = 0;
  static UINT16 u16_old_fault_word3 = 0;
  static UINT16 u16_old_motorfault_word1 = 0;
  static UINT16 u16_old_motorfault_word2 = 0;

  static UINT8 u8_5s_flag = 0;
  static UINT16 u16_version = 0;
  static UINT8 u8_DiDebugCnt = 0;


  static BOOL bFirstLockLiftOld;
  static BOOL bSecondLockLiftOld;
  static BOOL bPermanentLockLiftOld;
  static BOOL bEmergencyLockLiftOld;
  static INT16  nOldAverage;
  static UINT8 bOldChargePercent;
  union UN_LIFT_STATE unLiftState;
  static union UN_LIFT_STATE unOldLiftState;

  //can switch status
  unCanSwitchStatus.bit.bSwChassisDown = CHASSIS_DOWN_SW;
  unCanSwitchStatus.bit.bSwUpLimit = MAIN_Data.fUpLimit;
  unCanSwitchStatus.bit.bSwDownLimit = MAIN_Data.fDescentLimit;
  //unCanSwitchStatus.bit.bSwOverload = OVERLOAD_SENSOR;
  unCanSwitchStatus.bit.bSwPothole = POTHOLE_LIMIT;
  unCanSwitchStatus.bit.bSwKeySwitch = KEY_SWITCH;
  unCanSwitchStatus.bit.bSwChassisUp = CHASSIS_UP_SW;
  unCanSwitchStatus.bit.bSwTilt = LEVEL_SENSOR;

  //can joystick status
  unCanJoystickStatus.bit.bSwSlow = SW_HIGH;
  unCanJoystickStatus.bit.bSwHorn = SW_HORN;
  unCanJoystickStatus.bit.bSwEnable = SW_ENABLE;
  unCanJoystickStatus.bit.bSwRight = SW_RIGHT;
  unCanJoystickStatus.bit.bSwLeft = SW_LEFT;
  unCanJoystickStatus.bit.bSwLift = SW_LIFT;
  unCanJoystickStatus.bit.bSwDrive = SW_DRIVE;


   unLiftState.word = 0;
   if(MAIN_Data.bPCModeFlag)
      unLiftState.bit.bPcModeState = 1;
   else
   {
      if(MAIN_Data.eState == MAIN_INIT)
         unLiftState.bit.bInitState = 1;
      else if(MAIN_Data.eState == MAIN_WAIT_LINKUP)
         unLiftState.bit.bLinkupState = 1;
      else if(MAIN_Data.eState == MAIN_OPERATIONAL)
         unLiftState.bit.bOperationState = 1;
      else if(MAIN_Data.eState == MAIN_BRAKE_RELEASE)
         unLiftState.bit.bBrakeReleaseState = 1;
      else if(MAIN_Data.eState == MAIN_LOCKOUT)
         unLiftState.bit.bLockoutState = 1;
      else if(MAIN_Data.eState == MAIN_SPEED_ADJUST)
         unLiftState.bit.bMaintainState = 1;
      else
         ;
   }
	#if (CAN_DI_DEBUG == 1)
	if(++u8_DiDebugCnt>=5){u8_DiDebugCnt = 0;}
	switch(u8_DiDebugCnt)
	{
		case 3:
			u8_buffer[0] = (SWITCH_Data.wSwitches.word&0xff);
			u8_buffer[1] = ((SWITCH_Data.wSwitches.word>>8)&0xff);
			u8_buffer[2] =	u8J2_4Value;
			R_CAN0_Send(0x0000, 0x0666, 3, u8_buffer);
		break;
		default:break;
	}
	
	#endif
//if GPS_ALL_FUNCTION_FLAG=0,enable GPS
    if(1)//if(GPS_ENABLE_FLAG)
    {
		u16_version = 10 * (IMAGE_Descr.szName[ 0] -'0') + (IMAGE_Descr.szName[ 1] - '0');
		
		if(u16_Can_Tx_Cnt_500ms == DELAY_500MS)
		{
			if(u16_Can_Tx_Cnt_2 == 0)
			{
		        // organize data
		        u8_buffer[0] = (UINT8)(unCanFault1.word & 0xFF);                                      // lift fault word 1 low byte
		        u8_buffer[1] = (UINT8)((unCanFault1.word >> 8) & 0xFF);                               // lift fault word 1 high byte
		        u8_buffer[2] = (UINT8)(unCanFault2.word  & 0xFF);                                     // lift fault word 2 low byte
		        u8_buffer[3] = (UINT8)(u16_version & 0xFF);                                                         
		        u8_buffer[4] = (UINT8)((u16_version >> 8) & 0xFF); 
		        u8_buffer[5] = 0x00;
		        u8_buffer[6] = 0x00;
		        u8_buffer[7] = 0x00;
		        // send data
		        R_CAN0_Send(0x0000, 0x0101, 8, u8_buffer);
				u16_Can_Tx_Cnt_2++;
			}
			else if(u16_Can_Tx_Cnt_2 == 1)
			{
			   // organize data
			   u8_buffer[0] = (UINT8)(stHourMeter.u32Fraction & 0xFF);                                      // runtime low byte
			   u8_buffer[1] = (UINT8)((stHourMeter.u32Fraction >> 8) & 0xFF);                               // runtime high byte
			   u8_buffer[2] = (UINT8)((stHourMeter.u32Fraction >> 16) & 0xFF);                              // runtime low byte
			   u8_buffer[3] = (UINT8)((stHourMeter.u32Fraction >> 24) & 0xFF);                              // runtime high byte                          
               u8_buffer[4] = 0x00;
               u8_buffer[5] = 0x00;
               u8_buffer[6] = 0x00;
               u8_buffer[7] = 0x00;
               // send data
               R_CAN0_Send(0x0000, 0x0402, 8, u8_buffer);	
			   u16_Can_Tx_Cnt_2++;
			}
			else if(u16_Can_Tx_Cnt_2 == 2)
			{
				// organize data
				u8_buffer[0] = (UINT8)(LIFT_Data.calc_pwm1 & 0xFF);                                      // runtime low byte
				u8_buffer[1] = (UINT8)((LIFT_Data.calc_pwm1 >> 8) & 0xFF);                               // runtime high byte
				u8_buffer[2] = (UINT8)(MAIN_Data.wMeasured_Scissor_Angle & 0xFF);                              // runtime low byte
				u8_buffer[3] = (UINT8)((MAIN_Data.wMeasured_Scissor_Angle >> 8) & 0xFF);                              // runtime high byte
				u8_buffer[4] = (UINT8)(ui_Measured_Cylinder_Pressure & 0xFF);
				u8_buffer[5] = (UINT8)((ui_Measured_Cylinder_Pressure >> 8) & 0xFF);;
				u8_buffer[6] = (UINT8)(JOYSTICK_RAW_COUNTS & 0xFF);
				u8_buffer[7] = (UINT8)((JOYSTICK_RAW_COUNTS >> 8) & 0xFF);	
				// send data
				R_CAN0_Send(0x0000, 0x0502, 8, u8_buffer);
				u16_Can_Tx_Cnt_500ms = 0;
				u16_Can_Tx_Cnt_2 = 0;
			}
		}
		else
		{
			if(u16_Can_Tx_Cnt_20ms == 0)
			{
				// if tx channel 0 is ready
				if(1 == R_CAN0_Is_Transmitted(0))
				{
					// organize data
                    u8_buffer[0] = (UINT8)(Fets.word & 0xBF);                            // lift control word low byte
                    u8_buffer[1] = (UINT8)((Fets.word >> 8) & 0x01);                     // lift control word high byte
                    if(Fets.word&FET_BEACON)
						u8_buffer[1] |= 0x04;
					if(Fets.word&FET_ALARM)
						u8_buffer[1] |= 0x08;
                    u8_buffer[2] = (UINT8)(unCanSwitchStatus.word & 0xFF);
                    u8_buffer[3] = (UINT8)((unCanSwitchStatus.word >> 8) & 0xFF);
                    u8_buffer[4] = (UINT8)(unCanJoystickStatus.word & 0xFF);
                    u8_buffer[5] = (UINT8)((unCanJoystickStatus.word >> 8) & 0xFF);
                    u8_buffer[6] = 0x00;
                    u8_buffer[7] = 0x00;
                    // send data
                    R_CAN0_Send(0x0000, 0x0202, 8, u8_buffer);
                    u16_Can_Tx_Cnt_20ms++;
				}
			}
			else if(u16_Can_Tx_Cnt_20ms == 1)
			{
			   // organize data
                u8_buffer[0] = (UINT8)(unLiftlocksets.bit.bFirstLockLift+unLiftlocksets.bit.bSecondLockLift*2);                                      // lift switches word low byte
                u8_buffer[1] = (UINT8)(((UINT32)BATTERY_Local.nAverage*550l/1023) & 0xFF);                             // lift switches word high byte
                u8_buffer[2] = (UINT8)((((UINT32)BATTERY_Local.nAverage*550l/1023) >> 8) & 0xFF);                                   // lift joystick status low byte
                u8_buffer[3] = (UINT8)((BATTERY_Data.bChargePercent + 1) & 0xFF);                             // lift joystick status high byte
                u8_buffer[4] = (UINT8)(((BATTERY_Data.bChargePercent + 1) >> 8) & 0xFF);
                u8_buffer[5] = 0x00;
                u8_buffer[6] = (UINT8)(unLiftState.word & 0xFF);                                            // lift status word low byte
                u8_buffer[7] = 0x00;                                      // lift status word high byte
                // send data
                R_CAN0_Send(0x0000, 0x0302, 8, u8_buffer);
            u16_Can_Tx_Cnt_20ms = 0;
         }
      }

        //after entering into initial mode 10s, update the controller and application information
        if(MAIN_Data.eState == MAIN_WAIT_LINKUP)
        {
            u8_5s_flag = 1;
        }

        if((u16_Can_Tx_Cnt_5s < DELAY_5S) && (u8_5s_flag == 1))
        {
            u16_Can_Tx_Cnt_5s++;
        }

     if(u16_Can_Tx_Cnt_500ms < DELAY_500MS)
     {
        u16_Can_Tx_Cnt_500ms++;
     }

     if(u16_Can_Tx_Cnt_10min < DELAY_10MIN)
     {
        u16_Can_Tx_Cnt_10min++;
     }
  }
}
#endif


/******************************************************************************
* End of module
******************************************************************************/
